package com;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;


/**
 * debug过程中产生的日志信息默认全部写入日志文件中
 *
 * @author 大忽悠
 * @create 2023/1/11 13:24
 */
public class DebugPrinter extends PrintStream {
    /**
     * 默认写入到当前项目路径的debug.text文件中
     */
    private static final String DEFAULT_FILE_PATH = "debug.text";
    private PrintStream printStream;
    private static DebugPrinter debugPrinter;

    public DebugPrinter() throws FileNotFoundException {
        super(DEFAULT_FILE_PATH);
        printStream = new PrintStream(new FileOutputStream(DEFAULT_FILE_PATH, true), true);
    }

    /**
     * 不存在多线程竞争问题
     */
    public static DebugPrinter getInstance(){
        try {
            return debugPrinter!=null?debugPrinter:(debugPrinter=new DebugPrinter());
        } catch (FileNotFoundException e) {
              throw new RuntimeException(e);
        }
    }

    public void log(String logInfo) {
        println(logInfo);
    }

    public void setOutPutStream(OutputStream outPutStream) {
        printStream=new PrintStream(outPutStream,true);
    }

    @Override
    public void flush() {
        printStream.flush();
    }

    @Override
    public void close() {
        printStream.close();
    }

    @Override
    public boolean checkError() {
        return printStream.checkError();
    }

    @Override
    protected void setError() {
        try {
            Method setError = PrintStream.class.getDeclaredMethod("setError");
            setError.invoke(printStream);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
        }
    }

    @Override
    protected void clearError() {
        try {
            Method setError = PrintStream.class.getDeclaredMethod("clearError");
            setError.invoke(printStream);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
        }
    }

    @Override
    public void write(int b) {
        printStream.write(b);
    }


    @Override
    public void write(byte[] buf, int off, int len) {
        printStream.write(buf, off, len);
    }


    @Override
    public void print(boolean b) {
        printStream.print(b);
    }


    @Override
    public void print(char c) {
        printStream.print(c);
    }


    @Override
    public void print(int i) {
        printStream.print(i);
    }


    @Override
    public void print(long l) {
        printStream.print(l);
    }

    @Override
    public void print(float f) {
        printStream.print(f);
    }


    @Override
    public void print(double d) {
        printStream.print(d);
    }


    @Override
    public void print(char[] s) {
        printStream.print(s);
    }

    @Override
    public void print(String s) {
        printStream.print(s);
    }

    @Override
    public void print(Object obj) {
        printStream.print(obj);
    }

    @Override
    public void println() {
        printStream.println();
    }

    @Override
    public void println(boolean x) {
        printStream.println(x);
    }

    @Override
    public void println(char x) {
        printStream.println(x);
    }

    @Override
    public void println(int x) {
        printStream.println(x);
    }

    @Override
    public void println(long x) {
        printStream.println(x);
    }

    @Override
    public void println(float x) {
        printStream.println(x);
    }

    @Override
    public void println(double x) {
        printStream.println(x);
    }

    @Override
    public void println(char[] x) {
        printStream.println(x);
    }

    @Override
    public void println(String x) {
        printStream.println(x);
    }


    @Override
    public void println(Object x) {
        printStream.println(x);
    }

    @Override
    public PrintStream printf(String format, Object... args) {
        return printStream.printf(format, args);
    }

    @Override
    public PrintStream printf(Locale l, String format, Object... args) {
        return printStream.printf(l, format, args);
    }

    @Override
    public PrintStream format(String format, Object... args) {
        return printStream.format(format, args);
    }

    @Override
    public PrintStream format(Locale l, String format, Object... args) {
        return printStream.format(l, format, args);
    }

    @Override
    public PrintStream append(CharSequence csq) {
        return printStream.append(csq);
    }

    @Override
    public PrintStream append(CharSequence csq, int start, int end) {
        return printStream.append(csq, start, end);
    }

    @Override
    public PrintStream append(char c) {
        return printStream.append(c);
    }
    
    @Override
    public void write(byte[] b) throws IOException {
        printStream.write(b);
    }
}
